<template>
  <div class="chart-container">
    <div class="chart-header">
      <h3>用户留存分析</h3>
      <div class="controls">
        <div class="date-range-selector">
          <label for="cohort-range">选择日期范围：</label>
          <select id="cohort-range" v-model="selectedDateRange" @change="updateChart">
            <option value="all">全部日期</option>
            <option v-for="date in availableDates" :key="date" :value="date">
              {{ formatDate(date) }}
            </option>
          </select>
        </div>
        <div class="retention-type-selector">
          <label for="retention-type">留存类型：</label>
          <select id="retention-type" v-model="selectedRetentionType" @change="updateChart">
            <option value="reten1Rate">次日留存</option>
            <option value="reten3Rate">3日留存</option>
            <option value="reten5Rate">5日留存</option>
          </select>
        </div>
      </div>
    </div>
    <div ref="chart" style="width: 100%; height: 400px;"></div>
    
    <!-- 留存率统计表格 -->
    <div class="retention-table">
      <h4>用户留存率详情</h4>
      <div class="table-scroll-wrapper">
        <table>
          <thead>
            <tr>
              <th>日期</th>
              <th>次日留存率</th>
              <th>3日留存率</th>
              <th>5日留存率</th>
              <th>平均留存率</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in tableData" :key="index">
              <td><strong>{{ formatDate(item.day) }}</strong></td>
              <td :class="getRetentionCellClass(item.reten1Rate)">
                {{ formatRate(item.reten1Rate) }}
              </td>
              <td :class="getRetentionCellClass(item.reten3Rate)">
                {{ formatRate(item.reten3Rate) }}
              </td>
              <td :class="getRetentionCellClass(item.reten5Rate)">
                {{ formatRate(item.reten5Rate) }}
              </td>
              <td :class="getRetentionCellClass(item.averageRate)">
                <strong>{{ formatRate(item.averageRate) }}</strong>
              </td>
            </tr>
            <tr class="average-row">
              <td><strong>总体平均</strong></td>
              <td><strong>{{ formatRate(overallAverage.reten1Rate) }}</strong></td>
              <td><strong>{{ formatRate(overallAverage.reten3Rate) }}</strong></td>
              <td><strong>{{ formatRate(overallAverage.reten5Rate) }}</strong></td>
              <td><strong>{{ formatRate(overallAverage.averageRate) }}</strong></td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import { onMounted, ref, watch, onUnmounted, computed, nextTick } from 'vue';

export default {
  name: 'UserRetention',
  props: {
    chartData: {
      type: Array,
      default: () => []
    }
  },
  setup(props) {
    const chart = ref(null);
    let myChart = null;
    const selectedDateRange = ref('all');
    const selectedRetentionType = ref('reten1Rate');

    // 处理原始数据，确保日期排序
    const processedData = computed(() => {
      if (!props.chartData || props.chartData.length === 0) {
        return [];
      }
      
      // 按日期排序
      return [...props.chartData].sort((a, b) => new Date(a.day) - new Date(b.day));
    });

    // 获取可用日期
    const availableDates = computed(() => {
      return processedData.value.map(item => item.day);
    });

    // 处理表格数据
    const tableData = computed(() => {
      let dataToShow = processedData.value;
      
      if (selectedDateRange.value !== 'all') {
        dataToShow = processedData.value.filter(item => item.day === selectedDateRange.value);
      }
      
      // 计算每条数据的平均留存率
      return dataToShow.map(item => {
        const rates = [item.reten1Rate, item.reten3Rate, item.reten5Rate].filter(rate => rate > 0);
        const average = rates.length > 0 ? rates.reduce((sum, rate) => sum + rate, 0) / rates.length : 0;
        
        return {
          ...item,
          averageRate: average
        };
      });
    });

    // 计算总体平均值
    const overallAverage = computed(() => {
      if (tableData.value.length === 0) {
        return { reten1Rate: 0, reten3Rate: 0, reten5Rate: 0, averageRate: 0 };
      }
      
      const sums = { reten1Rate: 0, reten3Rate: 0, reten5Rate: 0, averageRate: 0 };
      let counts = { reten1Rate: 0, reten3Rate: 0, reten5Rate: 0, averageRate: 0 };
      
      tableData.value.forEach(item => {
        if (item.reten1Rate > 0) {
          sums.reten1Rate += item.reten1Rate;
          counts.reten1Rate++;
        }
        if (item.reten3Rate > 0) {
          sums.reten3Rate += item.reten3Rate;
          counts.reten3Rate++;
        }
        if (item.reten5Rate > 0) {
          sums.reten5Rate += item.reten5Rate;
          counts.reten5Rate++;
        }
        if (item.averageRate > 0) {
          sums.averageRate += item.averageRate;
          counts.averageRate++;
        }
      });
      
      return {
        reten1Rate: counts.reten1Rate > 0 ? sums.reten1Rate / counts.reten1Rate : 0,
        reten3Rate: counts.reten3Rate > 0 ? sums.reten3Rate / counts.reten3Rate : 0,
        reten5Rate: counts.reten5Rate > 0 ? sums.reten5Rate / counts.reten5Rate : 0,
        averageRate: counts.averageRate > 0 ? sums.averageRate / counts.averageRate : 0
      };
    });

    // 格式化日期显示
    const formatDate = (dateString) => {
      const date = new Date(dateString);
      return date.toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
      });
    };

    // 格式化比率显示
    const formatRate = (rate) => {
      return rate > 0 ? `${rate.toFixed(2)}%` : '-';
    };

    // 根据留存率获取单元格样式
    const getRetentionCellClass = (rate) => {
      if (rate === 0) return 'no-data';
      if (rate >= 80) return 'excellent-retention';
      if (rate >= 60) return 'good-retention';
      if (rate >= 40) return 'fair-retention';
      return 'poor-retention';
    };

    const initChart = () => {
      console.log('初始化用户留存趋势图');
      
      if (!chart.value) {
        console.error('图表容器未找到');
        return;
      }
      
      // 销毁旧的图表实例（如果存在）
      if (myChart) {
        myChart.dispose();
      }
      
      myChart = echarts.init(chart.value);
      
      const data = tableData.value;
      
      if (data.length === 0) {
        myChart.setOption({
          title: {
            text: '暂无留存数据',
            left: 'center',
            top: 'center'
          }
        });
        return;
      }
      
      // 获取留存类型对应的中文名称
      const retentionTypeNames = {
        reten1Rate: '次日留存',
        reten3Rate: '3日留存',
        reten5Rate: '5日留存'
      };
      
      // 准备图表数据
      const xAxisData = data.map(item => formatDate(item.day));
      const seriesData = data.map(item => item[selectedRetentionType.value]);
      
      const option = {
        title: {
          text: `用户${retentionTypeNames[selectedRetentionType.value]}趋势`,
          subtext: selectedDateRange.value === 'all' ? '全部日期' : `日期: ${formatDate(selectedDateRange.value)}`,
          left: 'center'
        },
        tooltip: {
          trigger: 'axis',
          formatter: function(params) {
            const item = data[params[0].dataIndex];
            return `
              <div style="text-align: left;">
                <div>日期: ${formatDate(item.day)}</div>
                <div>${retentionTypeNames[selectedRetentionType.value]}: ${formatRate(item[selectedRetentionType.value])}</div>
                <div>次日留存: ${formatRate(item.reten1Rate)}</div>
                <div>3日留存: ${formatRate(item.reten3Rate)}</div>
                <div>5日留存: ${formatRate(item.reten5Rate)}</div>
              </div>
            `;
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '15%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: xAxisData,
          axisLabel: {
            rotate: 45
          }
        },
        yAxis: {
          type: 'value',
          name: '留存率(%)',
          min: 0,
          max: 100,
          axisLabel: {
            formatter: '{value}%'
          }
        },
        series: [{
          name: retentionTypeNames[selectedRetentionType.value],
          type: 'line',
          data: seriesData,
          smooth: true,
          symbol: 'circle',
          symbolSize: 6,
          lineStyle: {
            width: 2
          },
          itemStyle: {
            color: '#5470c6'
          },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [{
                offset: 0, color: 'rgba(84, 112, 198, 0.3)'
              }, {
                offset: 1, color: 'rgba(84, 112, 198, 0.1)'
              }]
            }
          }
        }]
      };
      
      myChart.setOption(option);
      console.log('用户留存图表配置已设置');
    };

    const handleResize = () => {
      if (myChart) {
        myChart.resize();
      }
    };

    const updateChart = () => {
      if (myChart) {
        nextTick(() => {
          initChart();
        });
      }
    };

    onMounted(() => {
      console.log('用户留存组件挂载完成');
      
      window.addEventListener('resize', handleResize);
      
      // 使用nextTick确保DOM完全渲染
      nextTick(() => {
        initChart();
      });
    });

    onUnmounted(() => {
      window.removeEventListener('resize', handleResize);
      if (myChart) {
        myChart.dispose();
      }
    });

    // 监听数据变化
    watch(() => props.chartData, () => {
      nextTick(() => {
        initChart();
      });
    });

    // 监听筛选条件变化
    watch([selectedDateRange, selectedRetentionType], () => {
      nextTick(() => {
        initChart();
      });
    });

    return {
      chart,
      selectedDateRange,
      selectedRetentionType,
      availableDates,
      tableData,
      overallAverage,
      formatDate,
      formatRate,
      getRetentionCellClass,
      updateChart
    };
  }
}
</script>

<style scoped>
.chart-container {
  width: 100%;
  margin: 20px 0;
  padding: 20px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 15px;
}

.chart-header h3 {
  margin: 0;
  color: #333;
}

.controls {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}

.date-range-selector,
.retention-type-selector {
  display: flex;
  align-items: center;
  gap: 10px;
}

.date-range-selector label,
.retention-type-selector label {
  font-weight: bold;
  color: #666;
  white-space: nowrap;
}

.date-range-selector select,
.retention-type-selector select {
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #fff;
  min-width: 150px;
}

.retention-table {
  margin-top: 30px;
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 8px;
}

.retention-table h4 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #333;
  text-align: center;
}

.table-scroll-wrapper {
  overflow-x: auto;
  max-height: 400px; /* 限制表格高度，超出可滚动 */
  overflow-y: auto;
}

.retention-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 600px;
}

.retention-table th,
.retention-table td {
  padding: 12px;
  text-align: center;
  border: 1px solid #eaeaea;
}

.retention-table th {
  background-color: #f5f7fa;
  color: #606266;
  font-weight: bold;
  position: sticky;
  top: 0;
  z-index: 10;
}

.retention-table tr:hover {
  background-color: #f5f7fa;
}

/* 留存率样式 */
.excellent-retention {
  background-color: #f6ffed;
  color: #52c41a;
  font-weight: bold;
}

.good-retention {
  background-color: #fff7e6;
  color: #fa8c16;
  font-weight: bold;
}

.fair-retention {
  background-color: #fff2e8;
  color: #fa541c;
  font-weight: bold;
}

.poor-retention {
  background-color: #fff1f0;
  color: #f5222d;
  font-weight: bold;
}

.no-data {
  background-color: #fafafa;
  color: #999;
  font-style: italic;
}

.average-row {
  background-color: #e6f7ff;
  font-weight: bold;
}

.average-row td {
  border-top: 2px solid #1890ff;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .chart-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  
  .controls {
    flex-direction: column;
    gap: 10px;
    width: 100%;
  }
  
  .date-range-selector,
  .retention-type-selector {
    width: 100%;
  }
  
  .date-range-selector select,
  .retention-type-selector select {
    flex-grow: 1;
  }
  
  .retention-table {
    padding: 10px;
  }
  
  .retention-table table {
    font-size: 11px;
  }
  
  .retention-table th,
  .retention-table td {
    padding: 6px 4px;
  }
}
</style>
